<template>
  <a-spin :spinning="spinning" :delay="delayTime" tip="Loading...">
    <a-form-model
      ref="basicForm"
      :model="modelData"
      :rules="rules"
      :label-col="labelCol"
      :wrapper-col="wrapperCol"
    >
      <slot></slot>
      <slot name="operateBtn" v-if="showOperateBtn===true">
        <a-form-model-item :wrapper-col="{ span: 14, offset: 4 }" style="text-align:center">
          <a-button type="primary" @click="onSubmit">提交</a-button>
          <a-button style="margin-left: 10px;" @click="resetForm">重置</a-button>
        </a-form-model-item>
      </slot>
    </a-form-model>
  </a-spin>
</template>
<script>
import request from "@/utils/request";
import { objectToUrlParams } from "@/utils/tool-str";
export default {
  name: "BasicForm",
  model: {
    prop: "model",
    event: "change"
  },
  props: {
    //主键id
    primaryKey: {
      type: String,
      required: true
    },
    model: {
      type: Object,
      required: true
    },
    rules: {
      type: Object,
      default: () => {
        return {};
      }
    },
    labelCol: {
      type: Object,
      default: () => {
        return { span: 4 };
      }
    },
    wrapperCol: {
      type: Object,
      default: () => {
        return { span: 20 };
      }
    },
    queryApi: {
      type: String
    },
    insertApi: {
      type: String
    },
    updateApi: {
      type: String
    },
    //额外参数 {insert:{},update:{}}//兼容两种不同的情况
    extData: {
      type: Object,
      default: () => {
        return {};
      }
    },
    formType: {
      type: String,
      default: "form"
    },
    //显示表单页面操作按钮
    showOperateBtn: {
      type: Boolean,
      default: true
    }
  },
  data() {
    return {
      formState: undefined,
      modelData: this.model,
      spinning: false,
      delayTime: 500
    };
  },
  created() {
    this.initForm();
  },
  methods: {
    //初始化form表单
    initForm() {
      if (this.modelData[this.primaryKey]) {
        this.formState = "update";
        if (this.queryApi) this.getData();
      } else {
        this.formState = "add";
      }
    },
    getData() {
      this.spinning = true;
      request
        .get(this.queryApi + this.modelData[this.primaryKey])
        .then(response => {
          this.spinning = false;
          this.modelData = response.data.data;
        });
    },
    onSubmit() {
      this.$refs.basicForm.validate(valid => {
        if (!valid) {
          this.$message.error("请先填写表单必填元素！谢谢");
          return false;
        }
        // 新增

        if (this.formState == "add") {
          if (!this.insertApi) {
            this.$message.error("请先设置表单新增url");
            this.$emit("onInsert");
            return false;
          }
          this.onInsert();
        }
        //修改
        if (this.formState == "update") {
          if (!this.updateApi) {
            this.$message.error("请先设置表单修改url");
            this.$emit("onUpdate");
            return false;
          }
          this.onUpdate();
        }
      });
    },
    onInsert() {
      //将url进行一次转换，可以让用户自己追加额外参数进来
      let url = this.insertApi;
      let insertExtData = this.extData.insert;
      if (insertExtData)
        url += objectToUrlParams(insertExtData, url.indexOf("?") == -1);
      request.post(url, this.modelData).then(response => {
        let { data } = response.data;
        if (this.formType != "dialog") {
          //避免新增完成后页面不刷新
          var updateFormPath = this.$route.path + "/" + data[this.primaryKey];
          this.$router.replace({
            path: "/redirect" + updateFormPath
          });
        } else {
          this.modelData[this.primaryKey] = data[this.primaryKey];
          this.getData();
        }
        this.$emit("insertSuccess", data);
      });
    },
    onUpdate() {
      //将url进行一次转换，可以让用户自己追加额外参数进来
      let url = this.insertApi;
      let updateExtData = this.extData.update;
      if (updateExtData)
        url += objectToUrlParams(updateExtData, url.indexOf("?") == -1);
      request.post(this.updateApi, this.modelData).then(response => {
        let { data } = response.data;
        this.modelData[this.primaryKey] = data[this.primaryKey];
        this.getData();
        this.$emit("updateSuccess", data);
      });
    },
    resetForm() {
      this.$refs.basicForm.resetFields();
    }
  },
  watch: {
    modelData: function(val) {
      this.$emit("change", val);
    },
    model: function(val) {
      this.modelData = val;
    }
  }
};
</script>
